package com.harmony.pilot.knowledge.repository;

import com.harmony.pilot.knowledge.entity.CallRelation;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * 调用关系Repository
 */
@Repository
public interface CallRelationRepository extends JpaRepository<CallRelation, Long> {
    
    /**
     * 查找函数直接调用的所有函数
     */
    List<CallRelation> findByCallerName(String callerName);
    
    /**
     * 查找直接调用该函数的所有函数
     */
    List<CallRelation> findByCalleeName(String calleeName);
    
    /**
     * 查找跨仓调用
     */
    List<CallRelation> findByIsCrossRepoTrue();
    
    /**
     * 查找调用inner API的关系
     */
    List<CallRelation> findByIsInnerAPITrue();
    
    /**
     * 查找外部依赖
     */
    List<CallRelation> findByIsExternalTrue();
    
    /**
     * 查找特定仓库的跨仓调用
     */
    @Query("SELECT c FROM CallRelation c WHERE c.callerRepo = :repo AND c.isCrossRepo = true")
    List<CallRelation> findCrossRepoCallsByRepo(@Param("repo") String repo);
    
    /**
     * 查找调用链（需要递归，建议使用图数据库）
     */
    @Query(value = "WITH RECURSIVE call_chain AS (" +
                   "  SELECT caller_name, callee_name, 1 as depth " +
                   "  FROM call_relation " +
                   "  WHERE caller_name = :startFunction " +
                   "  UNION ALL " +
                   "  SELECT cr.caller_name, cr.callee_name, cc.depth + 1 " +
                   "  FROM call_relation cr " +
                   "  INNER JOIN call_chain cc ON cr.caller_name = cc.callee_name " +
                   "  WHERE cc.depth < :maxDepth" +
                   ") " +
                   "SELECT * FROM call_chain WHERE callee_name = :endFunction",
           nativeQuery = true)
    List<Object[]> findCallChain(@Param("startFunction") String startFunction,
                                 @Param("endFunction") String endFunction,
                                 @Param("maxDepth") int maxDepth);
}

